#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
作业是 基于上次的密码验证 写注册和登录 用户和密码的对应关系可以用字典存到pickle到文本上 祝好运 哈哈
重构上次密码验证的代码，优化了一部分逻辑。加密修改为字典并序列化储存。
'''
__author__ = 'chenwei'
__version__ = 'v1.1.0'
import hashlib,getpass,pickle,os
user_dict = {}
passwd_file='passwd_pickle.txt'

menu_list='''----登录菜单----
|1)登录(Login)    |
|2)注册(Create)   |
|3)退出(Quit)     |
----------------
请输入数字(1-3)或(l,c,q)： '''
welcome_menu_list = '''----用户菜单----
|1)未开放         |
|2)未开放         |
|3)退出(Quit)     |
----------------
请输入数字(1-3)或(q)：'''

def encrypt(arg):#加密函数
    try:
        return hashlib.sha512(arg.encode("utf-8")).hexdigest()
    except Exception as e:
        raise e

def open_file(fn,mode='rb'):#打开文件函数
     try:
         return open(fn,mode)
     except IOError as e:
        raise e

def load_user_dict():#从文件中读取用户字典
    if not os.path.exists(passwd_file) or not os.path.getsize(passwd_file) :
        return {}
    with open_file(passwd_file) as f:
        return pickle.load(f)

def welcome_interface(user_name):#登录成功后的交互界面
    while True:
        menu_value = 0 #初始化输入的menu_value值
        print("尊敬的",user_name,"，您好：")
        print_menu(welcome_menu_list)
        menu_value = input()
        if menu_value == '1' or menu_value == '2':
            print("该功能未开放")
        elif menu_value == '3' or menu_value == 'q' or menu_value == 'Q':
            break
    else:
        print("输入有误，请重新输入。")

def login_account(): #用户登录函数
    count = 0
    login_user_name = input("请输入用户名:")
    while count < 3:
        count += 1
        login_user_passwd = getpass.getpass("请输入密码:")
        if not check_passwd(login_user_name, login_user_passwd):
            print("登录失败。用户不存在或密码错误。请重试")
            continue
        print("登录成功。")
        welcome_interface(login_user_name)
        break
    else:
        print("输入错误超过三次，退出！")
def check_passwd(username, passwd): #登录检验密码函数
    try:
        if not username in user_dict or user_dict[username] != encrypt(passwd): #字典中没有这个用户 或 用户密码不相等 则返回假
            return False
        if user_dict[username] == encrypt(passwd): #用户密码相等 则返回真
            return True
    except Exception as e:
        raise e

def insert_account_to_passwd_file(username, passwd): #插入新的用户和密码到数据文件。
    if username in user_dict: #用户中是否有同名用户有则返回假
        return False
    user_dict[username] = encrypt(passwd) #把新用户的用户名和密码存入字典中
    with open_file(passwd_file, mode='w+b') as f:
        try:
            pickle.dump(user_dict,f)
        except Exception as e:
            raise e
    return True

def create_account(): #创建新账号函数
    create_user_name = input("请输入用户名:")
    create_user_passwd1 = getpass.getpass("请输入密码:")
    create_user_passwd2 = getpass.getpass("请再次输入密码:")
    if create_user_passwd1 == create_user_passwd2:
        create_result = insert_account_to_passwd_file(create_user_name, create_user_passwd1)
        if create_result :
            print("创建",create_user_name,"成功。")
        else:
            print("创建失败，用户名相同。")
    else:
        print("创建失败,两次密码输入不相同。")

def print_menu(this_list): #打印主页菜单
    print(this_list,end='')

def interactive_interface():
    while True:
        menu_value = 0 #初始化输入的menu_value值
        print_menu(menu_list)
        menu_value = input()
        if menu_value == '1' or menu_value == 'l' or menu_value == 'L':
            login_account()
        elif menu_value == '2' or menu_value == 'c' or menu_value == 'C':
            create_account()
        elif menu_value == '3' or menu_value == 'q' or menu_value == 'Q':
            break
    else:
        print("输入有误，请重新输入。")

if __name__ ==  __name__ :
    user_dict = load_user_dict()
    interactive_interface()